using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Misc;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using Ecng.Xaml;
using Ecng.Collections;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Storages;
using StockSharp.Algo.Testing;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.BusinessEntities;
using StockSharp.Xaml.Charting;
using StockSharp.Xaml.Charting.IndicatorPainters;
namespace SampleHistoryTesting
{
public partial class MainWindow
{
private ChartCandleElement _candlesElem;
private ChartTradeElement _tradeElement;
private ChartIndicatorElement _volumeElement;
private ChartIndicatorElement el;
private readonly ChartArea main;
private DateTime _startEmulationTime;
public MainWindow()
{
InitializeComponent();
main = new ChartArea()
{
YAxises =
{
new ChartAxis
{
Id = "Y2",
AxisType = ChartAxisType.Numeric,
AxisAlignment = ChartAxisAlignment.Left,
Group = "G1",
AutoRange = true,
}
},
XAxises =
{
new ChartAxis
{
Id = "X2",
Group = "G1",
AutoRange = true,
AxisType = ChartAxisType.Numeric,
AxisAlignment = ChartAxisAlignment.Top,
FlipCoordinates = true,
DrawMajorGridLines = false,
DrawMajorTicks = false,
DrawMinorGridLines = false,
DrawMinorTicks = false,
DrwaLables = false
}
},
};
CandleChart.Areas.Add(main);
_candlesElem = new ChartCandleElement();
_tradeElement = new ChartTradeElement();
_volumeElement = new ChartIndicatorElement
{
Color = Colors.DarkRed,
IsLegend = true,
Indicator = new VolumeIndicator(),
Title = "Volume",
YAxisId = "Y2",
};
el = new ChartIndicatorElement
{
Color = Colors.Red,
IsLegend = true,
Indicator = new VolumeProfileIndicator {UseTotalVolume = true, Step = 5, },
Title = "VolumeProfile",
DrawStyle = ChartIndicatorDrawStyles.StackedBar,
StrokeThickness = 3,
IndicatorPainter = new VolumeProfilePainter(),
YAxisId = "Y2",
XAxisId = "X2",
};
CandleChart.IsAutoScroll = true;
main.XAxises[0].AutoRange = true;
main.Elements.Add(_candlesElem);
main.Elements.Add(_tradeElement);
main.Elements.Add(_volumeElement);
main.Elements.Add(el);
}
private void StartBtnClick(object sender, RoutedEventArgs e)
{
var path = @"f:\History\";
var timeFrame = TimeSpan.FromMinutes(5);
var security = new Security
{
//Id = "RIZ2@FORTS", // по идентификатору инструмента будет искаться папка с историческими маркет данными
//Code = "RIZ2",
Name = "RTS-12.12",
Id = "SPFB.RTS@FORTS",
Code = "SPFB.RTS",
Class = "SPFB",
MinStepSize = 10,
MinStepPrice = 2,
MinPrice = 10,
MaxPrice = 1000000,
MarginBuy = 10000, // задаем ГО
MarginSell = 10000,
ExchangeBoard = ExchangeBoard.Forts,
};
// тестовый портфель
var portfolio = new Portfolio
{
Name = "test account",
BeginValue = 1000000,
};
// хранилище, через которое будет производиться доступ к тиковой и котировочной базе
/*-------------- Хранилище-------------------------------------*/
var storageRegistry = new StorageRegistry();
// Добавление в источник свечек TimeFrameCandleBuilder источник данных в виде файлов гидры
((LocalMarketDataDrive) storageRegistry.DefaultDrive).Path = path;
var startTime = new DateTime(2013, 1, 1);
var stopTime = new DateTime(2013, 1, 30);
// создаем шлюз для эмуляции
// инициализируем настройки (инструмент в истории обновляется раз в секунду)
var trader = new HistoryEmulationTrader(new[] {security}, new[] {portfolio})
{
StorageRegistry = storageRegistry,
MarketEmulator =
{
Settings =
{
// использовать стаканы
UseMarketDepth = true,
// использовать свечки
UseCandlesTimeFrame = TimeSpan.FromMinutes(5),
// проверка что стаканы соответствуют сделкам. Улучшает реалистичность тестирования.
SyncDepthToTrades = true,
// сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки.
// Если выключено - требуется "прохождение цены сквозь уровень"
// (более "суровый" режим тестирования.)
FillOnTouch = false,
}
}
};
((MessageAdapter) trader.MarketDataAdapter).MarketTimeChangedInterval = timeFrame;
trader.RegisterMarketDepth(new TrendMarketDepthGenerator(trader.GetSecurityId(security)));
trader.Connect();
trader.StartExport();
var candleManager = new CandleManager(trader);
var series = new CandleSeries(typeof (TimeFrameCandle), security, timeFrame);
// создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток
var strategy = new SmaStrategy(series, new SimpleMovingAverage {Length = 80},
new SimpleMovingAverage {Length = 10})
{
Volume = 1,
Portfolio = portfolio,
Security = security,
Trader = trader,
};
// копируем параметры на визуальную панель
ParameterGrid.Parameters.Clear();
ParameterGrid.Parameters.AddRange(strategy.StatisticManager.Parameters);
// и подписываемся на событие изменения времени, чтобы обновить ProgressBar
trader.MarketTimeChanged += a =>
{
var aa = a;
};
trader.NewMyTrades += (trade) =>
{
var t = timeFrame.GetCandleBounds(trade.Last().Trade.Time).Min;
this.GuiAsync(() =>CandleChart.ProcessValues(t,new Dictionary<IChartElement, object>{{_tradeElement, trade.Last()},}));
};
candleManager.Processing += (send, candle) =>
{
var vol1 = new ChartIndicatorValue(_volumeElement.Indicator, candle.TotalVolume) { IsFormed = true };
var vol2 = new VolumeProfileIndicatorValue();
if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() => CandleChart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, candle},
{_volumeElement, vol1},
// {el,vol2}
}));
}
};
candleManager.ProcessDataError += (a) =>
{
var aa = a;
};
candleManager.Stopped += (a) =>
{
var aa = a;
};
candleManager.Log += (a) =>
{
var aa = a;
};
trader.StateChanged += (oldState, newState) =>
{
if (trader.State == EmulationStates.Started)
{
// запускаем стратегию когда эмулятор запустился
strategy.Start();
candleManager.Start(series);
}
};
trader.ExportStarted += () =>
{
// strategy.Start();
// candleManager.Start(series);
};
// запускаем эмуляцию
// указываем даты начала и конца тестирования
trader.Start(startTime, stopTime);
}
}
}